package cn.hloger.spider.demo.authDemo.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * AES加解密工具类
 *
 * @author changxy
 */
@Slf4j
public class AESUtil {

    private final static String AES = "AES";
    private final static String UTF8 = "UTF-8";

    //定义一个16byte的初始向量
    private static final String DEFAULT_KEY = "202403251215hbjx";

    private static final String ENCRYPTOR_MODEL = "AES/CBC/PKCS5Padding";

    /**
     * AES加密
     *
     * @param content 明文
     * @return 返回加密后密文
     */
    public static String aesEncry(String content) {
        return aesEncry(content, DEFAULT_KEY);
    }

    /**
     * AES加密
     *
     * @param content 明文
     * @param key     密钥
     * @return 返回加密后密文
     */
    public static String aesEncry(String content, String key) {
        Assert.hasText(content, "明文不能为空");
        Assert.hasText(key, "密钥不能为空并且长度应该为16为位");
        try {
            byte[] contentByte = content.getBytes(UTF8);
//            byte[] keyByte = key.getBytes();
            byte[] keyByte = Base64.getDecoder().decode(key);

            //初始化一个密钥对象
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, AES);
            //初始化一个初始向量,不传入的话，则默认用全0的初始向量
            IvParameterSpec ivSpec = new IvParameterSpec(keyByte);
            // 指定加密的算法、工作模式和填充方式
            Cipher cipher = Cipher.getInstance(ENCRYPTOR_MODEL);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            byte[] encryptedBytes = cipher.doFinal(contentByte);
            String encodedString = Base64.getEncoder().encodeToString(encryptedBytes);
            return encodedString;
        } catch (Exception e) {
            log.error("AES加密时发生错误", e);
            return "AES加密时发生错误";
        }
    }

    /**
     * AES解密
     *
     * @param content 密文
     * @return 返回解密后明文
     */
    public static String aesDecry(String content) {
        return aesDecry(content, DEFAULT_KEY);
    }

    /**
     * AES解密
     *
     * @param content 密文
     * @param key     密钥
     * @return 返回解密后明文
     */
    public static String aesDecry(String content, String key) {
        Assert.hasText(content, "密文不能为空");
        Assert.hasText(key, "密钥不能为空并且长度应该为16为位");
        try {
            byte[] contentByte = Base64.getDecoder().decode(content);
            byte[] keyByte = Base64.getDecoder().decode(key);
            //初始化一个密钥对象
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, AES);
            //初始化一个初始向量,不传入的话，则默认用全0的初始向量
            IvParameterSpec ivSpec = new IvParameterSpec(keyByte);
            // 指定加密的算法、工作模式和填充方式
            Cipher cipher = Cipher.getInstance(ENCRYPTOR_MODEL);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] result = cipher.doFinal(contentByte);
            return new String(result, UTF8);
        } catch (Exception e) {
            log.error("AES解密时发生错误", e);
            return "AES解密时发生错误";
        }
    }

}
